import logging
import json
import os

from catalog.dip_catalog import DipCatalog
from patient.patient import PatientInfo
from series.agent.ai_analyze_medical import AiAnalyzeMedica
from series.rules.dip_series_rules import DIPGroupRules
from flask import Flask, request, jsonify
from flask_cors import CORS
from util.api_response import APIResponse
from util.exception_handler import handle_exceptions

logger = logging.getLogger(__name__)
# 创建Flask应用
app = Flask(__name__)
# 启用CORS支持
CORS(app)
# 配置JSON解析
app.config['JSON_AS_ASCII'] = False

# 配置日志
def setup_logger():
    # 创建logs目录
    log_dir = "logs"
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)

    # 配置日志格式
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        handlers=[
            logging.FileHandler(os.path.join(log_dir, 'dip_group_rules.log'), encoding='utf-8'),
            logging.StreamHandler()  # 同时输出到控制台
        ]
    )
    return logging.getLogger(__name__)


logger = setup_logger()


# 分析病历入口
class DipSeriesBlEntrance:


    def entrance(self, medical_text):
        logger.info("执行AI 入口方法")
        dip_group_rules = DIPGroupRules()
        dipCatalog = DipCatalog()
        ai_analyze_medica = AiAnalyzeMedica()

        # 从病历分析获取患者数据
        patient_json = ai_analyze_medica.call_bl_agent(medical_text)
        logger.info(f"病历分析结果: {patient_json}")

        # 检查是否返回错误
        if isinstance(patient_json, dict) and "错误" in patient_json:
            return {"错误": f"病历分析失败: {patient_json['错误']}"}

        # 解析JSON数据
        patient_data = json.loads(patient_json) if isinstance(patient_json, str) else patient_json

        # 转换数据格式以适配DIP分组系统
        converted_patient = self.convert_patient_data(patient_data)
        if converted_patient is None:
            return {"错误": "目录库找不到该诊断"}
        
        logger.info(f"转换后的患者数据: {converted_patient}")

        # 获取诊断编码进行目录库查询
        diagnosis_code = converted_patient.get('诊断编码')
        if not diagnosis_code:
            return {"错误": "未找到诊断编码，无法进行DIP分组"}

        # 查询核心目录库
        core_catalog_json = dipCatalog.load_core_catalog("诊断编码", diagnosis_code)
        if core_catalog_json is None:
            return {"错误": "目录库找不到该诊断"}
        
        logger.info(f"目录库查询结果: {core_catalog_json}")

        # 执行AI分析，获取结构化结果
        ai_result = dip_group_rules.execute_ai(converted_patient, core_catalog_json)

        # 返回解析结果
        parsed_data = ai_result['解析结果']
        return parsed_data

    def convert_patient_data(self, patient_data):
        """
        将病历分析的数据格式转换为DIP分组系统期望的格式
        """
        try:
            # 处理主诊断，提取诊断编码
            main_diagnosis = patient_data.get('主诊断', [])
            diagnosis_name = main_diagnosis[0] if main_diagnosis and main_diagnosis[0] != '无' else ""

            # 这里需要将诊断名称转换为诊断编码
            # 你可能需要一个诊断名称到编码的映射表
            diagnosis_code = self.get_diagnosis_code(diagnosis_name)

            # 处理手术编码
            main_surgery = patient_data.get('主手术', [])
            main_surgery_code = main_surgery[0] if main_surgery and main_surgery[0] != '无' else ""
            # main_surgery_code =self.get_surgery_code(main_surgery_name);

            other_surgery = patient_data.get('其它手术', [])
            other_surgery_code = other_surgery[0] if other_surgery and other_surgery[0] != '无' else ""
            # other_surgery_code =self.get_surgery_code(other_surgery_name);


            treatment = patient_data.get('治疗操作', [])
            treatment_code = treatment[0] if treatment and treatment[0] != '无' else ""
            # treatment_code =self.get_surgery_code(treatment_name);

            # 构建DIP系统期望的数据格式
            converted_data = {
                '患者姓名': patient_data.get('患者姓名', ''),
                '诊断编码': diagnosis_code,
                '诊断名称': diagnosis_name,
                '年龄': patient_data.get('患者年龄', 0),
                '住院天数': patient_data.get('住院天数', 0),
                '主手术': main_surgery_code,
                '其它手术': other_surgery_code,
                '治疗操作': treatment_code,
                '诊断操作': '',
                '总费用': '',
                '中医费用': ''
            }

            logger.info(f"数据转换完成: {converted_data}")
            return converted_data

        except Exception as e:
            logger.error(f"数据转换失败: {e}")
            return {}

    # 查询诊断编码
    def get_diagnosis_code(self, diagnosis_name):
        dipCatalog = DipCatalog()
        core_catalog_json =dipCatalog.load_core_catalog('诊断名称',diagnosis_name)
        res = json.loads(core_catalog_json)

        if res.get("status") == "not_found":
            return None
        conservative = [item for item in res["data"] if item.get("治疗方式") == "保守治疗"]
        return conservative[0]['诊断编码']
    #查询手术编码
    def get_surgery_code(self, surgery_name):
        dipCatalog = DipCatalog()
        core_catalog_json =dipCatalog.load_surgery('手术名称',surgery_name)
        res = json.loads(core_catalog_json)

        if res.get("status") == "not_found":
            return None
        conservative = [item for item in res["data"] ]
        return conservative[0]['手术编码']

@app.route('/api/dip/analyze_medical_text', methods=['POST'])
@handle_exceptions  # 自动处理异常
def analyze_medical_text():
    # 直接获取请求的原始文本数据
    medical_text = request.get_data(as_text=True)
    
    # 检查参数
    if not medical_text or medical_text.strip() == "":
        return APIResponse.error("医疗文本不能为空")

    bl = DipSeriesBlEntrance()
    response = bl.entrance(medical_text)
    
    # 检查是否返回错误
    if isinstance(response, dict) and "错误" in response:
        return APIResponse.error(response["错误"])
    
    # 返回成功响应
    return APIResponse.success(response, "医疗文本分析完成")



def main():
    # 注册智能报表路由
    from series.dip_report import register_routes
    register_routes(app)
    from series.dat.adjuvant_therapy import register_therapy_routes
    register_therapy_routes(app)
    # 启动Flask服务
    logger.info("启动DIP分组分析HTTP服务...")
    app.run(
        host='0.0.0.0',  # 允许外部访问
        port=5000,       # 端口号，可以根据需要修改
        debug=True       # 开发模式，生产环境建议设为False
    )


if __name__ == "__main__":
    main()